"""
生产管理服务
"""
import random
import os
import json
import glob
from datetime import datetime, timedelta
from typing import List, Dict, Any, Optional
from config import get_config
from .data_generator import DataGenerator
from app.utils.response import error_response

config = get_config()


class ProductionService:
    """生产管理服务类"""

    # -------- 文件数据装载（基于 data 目录的导出 JSON） --------
    _ORDERS_CACHE: Dict[str, Any] = {"path": None, "data": []}
    _DETAILS_CACHE: Dict[str, Any] = {"path": None, "data": []}

    @staticmethod
    def _data_dir() -> str:
        # 以本文件为基准定位到项目根目录，再拼 data
        base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
        return os.path.join(base_dir, "data")

    @staticmethod
    def _find_latest(pattern: str) -> Optional[str]:
        data_dir = ProductionService._data_dir()
        files = glob.glob(os.path.join(data_dir, pattern))
        if not files:
            return None
        # 取最近修改的一个
        return max(files, key=os.path.getmtime)

    @staticmethod
    def _load_json_array(path: str) -> List[Dict[str, Any]]:
        try:
            with open(path, "r", encoding="utf-8") as f:
                data = json.load(f)
                if isinstance(data, list):
                    return data
                # 如果不是数组，尝试包一层
                return [data]
        except Exception:
            return []

    @staticmethod
    def _load_orders_from_file() -> List[Dict[str, Any]]:
        latest = ProductionService._find_latest("erp_orders_*.json")
        if not latest:
            return []
        if ProductionService._ORDERS_CACHE["path"] != latest:
            ProductionService._ORDERS_CACHE["data"] = ProductionService._load_json_array(latest)
            ProductionService._ORDERS_CACHE["path"] = latest
        return ProductionService._ORDERS_CACHE["data"] or []

    @staticmethod
    def _load_details_from_file() -> List[Dict[str, Any]]:
        latest = ProductionService._find_latest("erp_order_details_*.json")
        if not latest:
            return []
        if ProductionService._DETAILS_CACHE["path"] != latest:
            ProductionService._DETAILS_CACHE["data"] = ProductionService._load_json_array(latest)
            ProductionService._DETAILS_CACHE["path"] = latest
        return ProductionService._DETAILS_CACHE["data"] or []

    @staticmethod
    def get_order_list(page_index: int, page_size: int, code: str = '', status: str = '',
                       is_show_process: int = 0, is_show_material: bool = False,
                       is_show_by_product: bool = False, is_show_activity: bool = False) -> dict:
        """获取生产订单列表 - 用友云标准格式
        优先从 data/erp_orders_*.json 装载；不存在时回退到脚本生成。
        """
        orders = ProductionService._load_orders_from_file()

        if orders:
            # 可选：简单过滤（按 code 包含，按 status 等于）
            filtered = orders
            if code:
                c = str(code).strip()
                filtered = [x for x in filtered if str(x.get("code", "")).find(c) != -1]
            if status != "":
                filtered = [x for x in filtered if str(x.get("status", "")) == str(status)]

            total = len(filtered)
            start_idx = max(0, (page_index - 1) * page_size)
            end_idx = min(start_idx + page_size, total)
            page_records = filtered[start_idx:end_idx]
            page_count = (total + page_size - 1) // page_size if page_size > 0 else 1

            sum_record_list = ProductionService._generate_sum_record(page_records)

            return {
                "pageIndex": page_index,
                "pageSize": page_size,
                "recordCount": total,
                "recordList": page_records,
                "sumRecordList": sum_record_list,
                "pageCount": page_count,
                "beginPageIndex": 1,
                "endPageIndex": page_count,
                "pubts": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }

        # 回退：使用生成器
        record_list: List[Dict[str, Any]] = []
        total_orders = 156
        start_idx = (page_index - 1) * page_size
        end_idx = min(start_idx + page_size, total_orders)
        records_to_generate = max(0, end_idx - start_idx)
        page_count = (total_orders + page_size - 1) // page_size

        for i in range(records_to_generate):
            order_num = start_idx + i + 1
            if order_num <= total_orders:
                order = DataGenerator.generate_realistic_order(order_num)
                record = ProductionService._generate_yonyou_order_record(
                    order,
                    is_show_process,
                    is_show_material,
                    is_show_by_product,
                    is_show_activity,
                )
                record_list.append(record)

        sum_record_list = ProductionService._generate_sum_record(record_list)
        return {
            "pageIndex": page_index,
            "pageSize": page_size,
            "recordCount": total_orders,
            "recordList": record_list,
            "sumRecordList": sum_record_list,
            "pageCount": page_count,
            "beginPageIndex": 1,
            "endPageIndex": page_count,
            "pubts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        }

    @staticmethod
    def _generate_yonyou_order_record(order: dict, is_show_process: int = 0,
                                       is_show_material: bool = False,
                                       is_show_by_product: bool = False,
                                       is_show_activity: bool = False) -> dict:
        """生成用友云标准格式的订单记录（80+字段）"""
        product_info = order["product_info"]

        # 生成随机ID（用友云使用16位长整型）
        order_id = random.randint(2000000000000000, 3000000000000000)
        order_product_id = random.randint(2000000000000000, 3000000000000000)
        material_id = random.randint(2000000000000000, 3000000000000000)
        product_id = random.randint(2000000000000000, 3000000000000000)
        sku_id = random.randint(2000000000000000, 3000000000000000)

        # 基础记录（80+字段按用友文档）
        record = {
            # 订单主表字段
            "id": order_id,
            "code": order["code"],
            "status": order["status"],
            "vouchdate": order["created_time"][:10] + " 00:00:00",
            "createTime": order["created_time"],
            "creator": order["created_by"],
            "creatorId": random.randint(1000000000000000, 2000000000000000),
            "pubts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),

            # 组织和部门
            "orgId": str(random.randint(1000000000000000, 2000000000000000)),
            "orgName": order["organization"],
            "productionDepartmentId": str(random.randint(1000000000000000, 2000000000000000)),
            "departmentName": order["department"],

            # 交易类型
            "transTypeId": str(random.randint(1000000000000000, 2000000000000000)),
            "transTypeCode": "PO-001",
            "transTypeName": "标准生产",

            # 审批状态
            "verifystate": 0,  # 0-开立，1-已提交，2-已审批，-1-驳回
            "isWfControlled": False,
            "returncount": 0,
            "auditTime": None if order["status"] == "0" else datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "auditDate": None if order["status"] == "0" else datetime.now().strftime("%Y-%m-%d"),

            # 挂起状态
            "isHold": False,

            # 受托加工
            "entrustProcessType": random.choice([2, 3]) if random.random() < 0.2 else None,
            "entrustCustomer": random.randint(1000000000000000, 2000000000000000) if random.random() < 0.2 else None,
            "entrustCustomerName": "受托客户" if random.random() < 0.2 else None,

            # 表外产出
            "offChartReceiptIsAllowed": random.choice([True, False]),

            # 排程相关
            "apsLock": 0,  # 0-未锁定，1-已锁定
            "dailyschQuantity": random.randint(0, int(order["planned_quantity"])) if random.random() < 0.3 else 0,
            "dailyschStatus": random.choice([0, 1, 2]),  # 0-未排产，1-部分排产，2-已排产
            "dailyschConquantity": random.randint(0, int(order["planned_quantity"])) if random.random() < 0.3 else 0,

            # OrderProduct（产品行）字段 - 所有以OrderProduct_开头
            "orderProduct_id": order_product_id,
            "OrderProduct_lineNo": 10,

            # 物料信息
            "OrderProduct_materialId": material_id,
            "OrderProduct_materialCode": product_info["material_code"],
            "OrderProduct_materialName": product_info["material_name"],
            "OrderProduct_productId": product_id,
            "OrderProduct_productCode": product_info["material_code"],
            "OrderProduct_productName": product_info["material_name"],
            "OrderProduct_skuId": sku_id,
            "OrderProduct_skuCode": product_info["material_code"],
            "OrderProduct_skuName": product_info["material_name"],

            # 数量信息
            "OrderProduct_quantity": order["planned_quantity"],
            "OrderProduct_auxiliaryQuantity": order["planned_quantity"],
            "OrderProduct_completedQuantity": order["completed_quantity"],
            "OrderProduct_incomingQuantity": order["qualified_quantity"],
            "OrderProduct_mrpQuantity": order["planned_quantity"],

            # 单位和精度
            "OrderProduct_productionUnitId": random.randint(1000000000000000, 2000000000000000),
            "OrderProduct_productUnitName": product_info["unit"],
            "productUnitPrecision": 3,
            "OrderProduct_mainUnit": random.randint(1000000000000000, 2000000000000000),
            "OrderProduct_mainUnitName": product_info["unit"],
            "mainUnitPrecision": 3,

            # 换算方式
            "OrderProduct_changeType": 0,  # 0-固定换算，1-浮动换算
            "OrderProduct_changeRate": 1.0,

            # 舍位方式
            "OrderProduct_productUnitTruncationType": 4,  # 0-入位，1-舍位，4-四舍五入
            "OrderProduct_mainUnitTruncationType": 4,

            # 日期
            "OrderProduct_startDate": order["plan_start_date"],
            "OrderProduct_finishDate": order["plan_end_date"],

            # 组织
            "OrderProduct_orgId": str(random.randint(1000000000000000, 2000000000000000)),
            "OrderProduct_orgName": order["organization"],

            # BOM相关
            "OrderProduct_bomId": random.randint(1000000000000000, 2000000000000000),
            "OrderProduct_versionCode": random.choice(["A1", "B1", "C1", "V1.0"]),

            # 工艺路线
            "routingId": random.randint(1000000000000000, 2000000000000000),
            "routingCode": f"RT{random.randint(1000, 9999)}",
            "routingName": f"{product_info['product_type']}工艺路线",
            "routingVersion": "1.0",

            # 来源类型
            "OrderProduct_sourceType": random.choice(["1", "2", "3"]),  # 1-无来源，2-计划订单，3-销售订单

            # 废品率
            "OrderProduct_scrap": random.randint(0, 5),

            # 标志位
            "OrderProduct_completedFlag": True,
            "OrderProduct_materialApplyFlag": random.choice([True, False]),
            "OrderProduct_retMaterialApplyFlag": random.choice([0, 1]),
            "OrderProduct_isHold": False,

            # 状态字段
            "OrderProduct_materialApplyStatus": random.choice([0, 1, 2, 3]),  # 0-未申领，1-部分申领，2-全部申领，3-无需申领
            "OrderProduct_materialStatus": random.choice([0, 1, 2, 3, 4]),  # 0-未领料，1-部分领用，2-全部领用，3-无需领料，4-超额领料
            "OrderProduct_finishedWorkApplyStatus": random.choice([0, 1, 2]),  # 0-未申报，1-部分申报，2-全部申报
            "OrderProduct_stockStatus": random.choice([0, 1, 2]),  # 0-未入库，1-部分入库，2-全部入库

            # 外部系统来源（可选）
            "out_sys_id": None,
            "out_sys_code": None,
            "out_sys_version": None,
            "out_sys_type": None,
            "out_sys_rowno": None,
            "out_sys_lineid": None,

            # 项目相关（可选）
            "OrderProduct_projectId": None,
            "OrderProduct_projectCode": None,
            "OrderProduct_projectName": None,
            "OrderProduct_wbs": None,
            "OrderProduct_wbsCode": None,
            "OrderProduct_wbsName": None,
            "OrderProduct_activity": None,
            "OrderProduct_activityCode": None,
            "OrderProduct_activityName": None,

            # 确认数量（可选）
            "cfmIncomingQty": order["qualified_quantity"],
            "cfmIncomingAuxQty": order["qualified_quantity"],
            "cfmScrapStockQty": order["scrap_quantity"],
            "cfmScrapStockAuxQty": order["scrap_quantity"],
            "cfmReceivedKit": 0,

            # 首检相关（可选）
            "firstCheck": "0",
            "firstCheckType": "0",
            "firstCheckStatus": "0"
        }

        # 根据参数添加嵌套对象
        if is_show_material:
            record["orderMaterial"] = ProductionService._generate_order_materials(
                order, product_info, order_product_id
            )

        if is_show_process > 0:
            record["orderProcess"] = ProductionService._generate_order_processes(
                order, product_info, order_id, order_product_id, is_show_process
            )

        if is_show_activity:
            record["orderActivity"] = ProductionService._generate_order_activities(
                order, product_info, order_id, order_product_id
            )

        if is_show_by_product:
            record["orderByProduct"] = ProductionService._generate_order_by_products(
                order, product_info, order_product_id
            )

        return record

    @staticmethod
    def _generate_order_materials(order: dict, product_info: dict, order_product_id: int) -> list:
        """生成订单材料明细（orderMaterial）- 用友云标准格式"""
        # 使用DataGenerator生成基础材料数据
        base_materials = DataGenerator.generate_order_materials(
            product_info, order["planned_quantity"]
        )

        materials = []
        for idx, base_mat in enumerate(base_materials):
            # 生成随机ID
            material_detail_id = random.randint(2000000000000000, 3000000000000000)
            material_id = random.randint(2000000000000000, 3000000000000000)
            product_id = random.randint(2000000000000000, 3000000000000000)
            sku_id = random.randint(2000000000000000, 3000000000000000)
            bom_material_id = random.randint(2000000000000000, 3000000000000000)

            # 数量计算
            recipient_qty = base_mat["required_quantity"]
            received_qty = base_mat["issued_quantity"]
            # 单位使用数量 = 应领数量 / 生产数量
            unit_use_qty = round(recipient_qty / order["planned_quantity"], 8) if order["planned_quantity"] > 0 else 0
            auxiliary_recipient_qty = recipient_qty
            auxiliary_received_qty = received_qty

            # 超额数量（可选）
            excess_rate = random.randint(10, 50)  # 超额比例10%-50%
            excess_qty = int(recipient_qty * excess_rate / 100)
            excess_applied_qty = random.randint(0, excess_qty) if random.random() < 0.3 else 0
            excess_recipient_qty = random.randint(0, excess_applied_qty) if excess_applied_qty > 0 else 0

            # 退料数量（可选）
            applied_ret_qty = random.randint(0, int(received_qty * 0.1)) if received_qty > 0 and random.random() < 0.2 else 0
            applied_ret_rest_qty = int(applied_ret_qty * random.uniform(0, 1)) if applied_ret_qty > 0 else 0

            # 确认数量
            cfm_received_qty = received_qty
            cfm_aux_received_qty = auxiliary_received_qty
            cfm_excess_recipient_qty = excess_recipient_qty
            cfm_received_kit = int(received_qty / unit_use_qty) if unit_use_qty > 0 else 0

            material = {
                # 基础字段
                "id": material_detail_id,
                "lineNo": (idx + 1) * 10,
                "orderProductId": order_product_id,

                # 物料信息
                "materialId": material_id,
                "materialCode": base_mat["material_code"],
                "materialName": base_mat["material_name"],
                "productId": product_id,
                "productCode": base_mat["material_code"],
                "productName": base_mat["material_name"],
                "skuId": sku_id,
                "skuCode": base_mat["material_code"],
                "skuName": base_mat["material_name"],

                # 组织
                "orgId": str(random.randint(1000000000000000, 2000000000000000)),
                "orgName": order["organization"],

                # 数量信息
                "recipientQuantity": recipient_qty,
                "receivedQuantity": received_qty,
                "auxiliaryRecipientQuantity": auxiliary_recipient_qty,
                "auxiliaryReceivedQuantity": auxiliary_received_qty,
                "unitUseQuantity": unit_use_qty,
                "numeratorQuantity": unit_use_qty,
                "denominatorQuantity": 1,
                "mustLossQuantity": 0,

                # 单位和精度
                "stockUnitId": random.randint(1000000000000000, 2000000000000000),
                "stockUnitName": base_mat["unit"],
                "stockUnitPrecision": 7,
                "stockUnitTruncationType": 1,  # 1-舍位
                "mainUnit": random.randint(1000000000000000, 2000000000000000),
                "mainUnitName": base_mat["unit"],
                "mainUnitPrecision": 7,
                "mainUnitTruncationType": 1,

                # 换算
                "changeRate": 1.0,
                "changeType": 0,  # 0-固定换算

                # BOM信息
                "bomId": random.randint(1000000000000000, 2000000000000000),
                "bomMaterialId": bom_material_id,

                # 供料方式
                "supplyType": base_mat.get("issue_type", "0"),  # 0-领用，1-入库倒冲，2-不发料

                # 废品率和标志
                "scrap": random.randint(0, 5),
                "isWholeSet": random.choice([True, False]),
                "substituteFlag": random.choice([0, 1]),
                "truncUp": 0,
                "fixedQuantity": 0,
                "calcCostFlag": 1,

                # 需求日期
                "requirementDate": order["plan_start_date"],

                # 时间戳
                "pubts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),

                # 扩展信息（orderMaterialExpinfo前缀）
                "orderMaterialExpinfo!id": random.randint(1000000000000000, 2000000000000000),
                "orderMaterialExpinfo!isExcess": random.choice([True, False]),
                "orderMaterialExpinfo!excessType": random.choice([1, 2, 3]),  # 1-比例，2-数量，3-不控制
                "orderMaterialExpinfo!excessRate": excess_rate,
                "orderMaterialExpinfo!fixedExcessQty": excess_qty,
                "orderMaterialExpinfo!excessQty": excess_qty,
                "orderMaterialExpinfo!auxiliaryExcessQty": excess_qty,
                "orderMaterialExpinfo!designator": f"LOC{random.randint(1000, 9999)}",
                "orderMaterialExpinfo!wholePoint": random.choice(["1", "2", "3", "4"]),  # 1-订单完工，2-订单入库，3-订单开工，4-工序完工

                # 超额领料
                "excessAppliedQty": excess_applied_qty,
                "auxiliaryExcessAppliedQty": excess_applied_qty,
                "excessRecipientQty": excess_recipient_qty,
                "auxiliaryExcessRecipientQty": excess_recipient_qty,

                # 退料申请
                "appliedRetQuantity": applied_ret_qty,
                "auxiliaryAppliedRetQuantity": applied_ret_qty,
                "appliedRetRestQuantity": applied_ret_rest_qty,
                "auxiliaryAppliedRetRestQuantity": applied_ret_rest_qty,

                # 超额退料
                "excessAppliedRetQty": int(applied_ret_qty * 0.5) if applied_ret_qty > 0 else 0,
                "auxiliaryExcessAppliedRetQty": int(applied_ret_qty * 0.5) if applied_ret_qty > 0 else 0,
                "excessAppliedRetRestQty": int(applied_ret_rest_qty * 0.5) if applied_ret_rest_qty > 0 else 0,
                "auxiliaryExcessAppliedRetRestQty": int(applied_ret_rest_qty * 0.5) if applied_ret_rest_qty > 0 else 0,

                # 未出库数量
                "appliedRestQuantity": recipient_qty - received_qty,
                "auxiliaryAppliedRestQuantity": auxiliary_recipient_qty - auxiliary_received_qty,
                "excessAppliedRestQty": excess_applied_qty - excess_recipient_qty,
                "auxiliaryExcessAppliedRestQty": excess_applied_qty - excess_recipient_qty,

                # 项目相关（可选）
                "projectId": None,
                "projectCode": None,
                "projectName": None,
                "wbs": None,
                "wbsCode": None,
                "wbsName": None,
                "activity": None,
                "activityCode": None,
                "activityName": None,

                # 确认数量
                "cfmReceivedQty": cfm_received_qty,
                "cfmAuxReceivedQty": cfm_aux_received_qty,
                "cfmExcessRecipientQty": cfm_excess_recipient_qty,
                "cfmExcessAuxQty": cfm_excess_recipient_qty,
                "cfmReceivedKit": cfm_received_kit
            }

            materials.append(material)

        return materials

    @staticmethod
    def _generate_order_processes(order: dict, product_info: dict, order_id: int,
                                   order_product_id: int, is_show_process: int) -> list:
        """生成订单工序明细（orderProcess）- 用友云标准格式

        Args:
            order: 订单数据
            product_info: 产品信息
            order_id: 订单ID
            order_product_id: 订单产品行ID
            is_show_process: 0-不展示；1-全部工序；2-全部工序（含执行信息）；3-未执行完工序
        """
        # 使用DataGenerator生成基础工序数据
        base_processes = DataGenerator.generate_order_processes(
            product_info["product_type"]
        )

        processes = []
        prev_process_id = None

        for idx, base_proc in enumerate(base_processes):
            # 生成随机ID
            process_id = random.randint(2000000000000000, 3000000000000000)
            operation_id = random.randint(2000000000000000, 3000000000000000)
            work_center_id = random.randint(2000000000000000, 3000000000000000)
            operation_control_id = random.randint(2000000000000000, 3000000000000000)
            routing_operation_id = random.randint(2000000000000000, 3000000000000000)

            # 数量信息
            plan_qty = order["planned_quantity"]
            plan_prod_qty = plan_qty

            # 累计完成数量（根据订单状态）
            if order["status"] == "9":  # 已完工
                total_complete = plan_qty
                total_qualified = order["qualified_quantity"]
                total_scrap = order["scrap_quantity"]
            elif order["status"] == "5":  # 已开工
                total_complete = order["completed_quantity"]
                total_qualified = int(total_complete * random.uniform(0.92, 0.99))
                total_scrap = total_complete - total_qualified
            else:  # 未开工
                total_complete = 0
                total_qualified = 0
                total_scrap = 0

            total_rework = random.randint(0, int(total_scrap * 0.3))
            total_turn = total_qualified + total_rework

            # 换算率
            main_change_rate = 1.0
            out_change_rate = 1.0

            # 工序信息
            sn = base_proc["sequence"]
            next_sn = base_processes[idx + 1]["sequence"] if idx + 1 < len(base_processes) else None
            pre_sn = base_processes[idx - 1]["sequence"] if idx > 0 else None
            next_id = processes[idx - 1]["id"] if idx > 0 else None  # 后序ID实际是前一个工序的ID

            # 时间单位：1-小时
            time_unit = 1
            prepare_time = base_proc.get("setup_time", 0.5)
            process_time = base_proc.get("process_time", 2.0)
            standard_process_time = int(process_time * 60)  # 分钟

            # 组织信息
            org_id = str(random.randint(1000000000000000, 2000000000000000))
            execute_org_id = org_id

            process = {
                # 基础字段
                "id": process_id,
                "orderId": order_id,
                "orderProductId": order_product_id,
                "sn": sn,
                "nextSn": next_sn,
                "preSn": pre_sn,
                "nextId": next_id,

                # 工序信息
                "operationId": operation_id,
                "operationCode": base_proc["process_code"],
                "operationName": base_proc["process_name"],
                "routingOperationId": routing_operation_id,
                "operationIdRouteDesc": f"{base_proc['process_name']}工艺描述",
                "routingOperationProcessTime": standard_process_time,

                # 工作中心
                "workCenterId": work_center_id,
                "workCenterCode": base_proc["work_center_id"],
                "workCenterName": base_proc["work_center_name"],

                # 工序控制码
                "operationControlId": operation_control_id,
                "operationControlCode": f"CTRL{random.randint(100, 999)}",
                "operationControlName": random.choice(["车间检验", "自检", "免检", "抽检"]),

                # 组织
                "orgId": org_id,
                "orgName": order["organization"],
                "executeOrgId": execute_org_id,
                "executeOrgName": order["organization"],

                # 数量信息
                "qty": plan_qty,
                "prodQty": plan_prod_qty,
                "scheduleProdNum2": plan_qty,  # 计划加工数量（产出单位）

                # 单位和精度
                "mainUnitId": random.randint(1000000000000000, 2000000000000000),
                "mainUnitName": product_info["unit"],
                "mainUnitPrecision": 8,
                "mainUnitTruncationType": 4,  # 四舍五入
                "productionUnitId": random.randint(1000000000000000, 2000000000000000),
                "productUnitName": product_info["unit"],
                "productUnitPrecision": 8,
                "productUnitTruncationType": 4,
                "outUnitId": random.randint(1000000000000000, 2000000000000000),
                "outUnitName": product_info["unit"],
                "outUnitPrecision": 8,
                "outUnitTruncationType": 4,

                # 换算
                "changeType": 0,  # 0-固定换算
                "mainChangeRate": main_change_rate,
                "outChangeRate": out_change_rate,

                # 时间信息
                "planStartDate": order["plan_start_date"],
                "planEndDate": order["plan_end_date"],
                "prepareTime": prepare_time,
                "processTime": process_time,
                "timeUnit": time_unit,

                # 标志位
                "doScheduling": random.choice([0, 1]),  # 参与调度
                "occupyProduction": random.choice([0, 1]),  # 占用产能
                "computingCosts": random.choice([0, 1]),  # 计算成本
                "immediateHandover": random.choice([0, 1]),  # 即时交接
                "isOutsource": 0,  # 委外
                "reportWork": random.choice([0, 1]),  # 报工
                "checkType": random.choice([0, 1]),  # 0-自检，1-车间检验
                "firstCheck": random.choice([0, 1]),  # 首检

                # 仓库
                "finishWarehouseId": random.randint(1000000000000000, 2000000000000000),
                "finishGoodsId": random.randint(1000000000000000, 2000000000000000),

                # 加工类型
                "processType": 0,  # 0-正常加工，1-返工生产，2-报废补投

                # 工序作业计划
                "procPlanCreate": 0,
                "transferProcplanQty": 0,
                "transferProcplanProdQty": 0,

                # 时间戳
                "pubts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),

                # 累计完成数量（18个累计字段）
                "totalCompleteNum": total_complete,
                "totalCompleteNum1": total_complete,
                "totalCompleteNum2": total_complete,
                "totalQualifiedNum": total_qualified,
                "totalQualifiedNum1": total_qualified,
                "totalQualifiedNum2": total_qualified,
                "totalScrapNum": total_scrap,
                "totalScrapNum1": total_scrap,
                "totalScrapNum2": total_scrap,
                "totalReworkNum": total_rework,
                "totalReworkNum1": total_rework,
                "totalReworkNum2": total_rework,
                "totalReworkProcessNum": int(total_rework * 0.8),
                "totalReworkProcessNum1": int(total_rework * 0.8),
                "totalReworkProcessNum2": int(total_rework * 0.8),
                "totalTurnNum": total_turn,
                "totalTurnNum1": total_turn,
                "totalTurnNum2": total_turn,
                "totalQualifiedTurnNum": total_qualified,
                "totalQualifiedTurnNum1": total_qualified,
                "totalQualifiedTurnNum2": total_qualified,
                "totalReworkTurnNum": total_rework,
                "totalReworkTurnNum1": total_rework,
                "totalReworkTurnNum2": total_rework,
                "scrapInNum": total_scrap,
                "scrapInNum1": total_scrap,
                "scrapInNum2": total_scrap,

                # 外部系统来源（可选）
                "out_sys_id": None,
                "out_sys_code": None,
                "out_sys_version": None,
                "out_sys_type": None,
                "out_sys_rowno": None,
                "out_sys_lineid": None,

                # 项目相关（可选）
                "OrderProduct_projectId": None,
                "OrderProduct_projectCode": None,
                "OrderProduct_projectName": None,
                "OrderProduct_wbs": None,
                "OrderProduct_wbsCode": None,
                "OrderProduct_wbsName": None,
                "OrderProduct_activity": None,
                "OrderProduct_activityCode": None,
                "OrderProduct_activityName": None,

                # 确认数量（可选）
                "cfmIncomingQty": total_qualified,
                "cfmIncomingAuxQty": total_qualified,
                "cfmScrapStockQty": total_scrap,
                "cfmScrapStockAuxQty": total_scrap,
                "cfmReceivedKit": 0,

                # 首检相关
                "firstCheckType": random.choice(["0", "1"]),  # 0-不控制，1-严格
                "firstCheckStatus": random.choice(["0", "1", "2", "3", "4"])  # 0-无需首检，1-待首检，2-首检中，3-首检合格，4-首检不合格
            }

            processes.append(process)
            prev_process_id = process_id

        # 根据is_show_process参数过滤工序
        if is_show_process == 3:  # 仅显示未执行完工序
            processes = [p for p in processes if p["totalCompleteNum"] < p["qty"]]

        return processes

    @staticmethod
    def _generate_order_activities(order: dict, product_info: dict, order_id: int,
                                   order_product_id: int) -> list:
        """生成订单作业明细（orderActivity）- 用友云标准格式"""
        # 基于工序生成作业（每个工序可能有多个作业）
        base_processes = DataGenerator.generate_order_processes(product_info["product_type"])

        activities = []
        line_num = 10

        for proc_idx, base_proc in enumerate(base_processes):
            # 每个工序生成1-3个作业
            num_activities = random.randint(1, 3)

            for act_idx in range(num_activities):
                activity_id = random.randint(2000000000000000, 3000000000000000)
                activity_type_id = random.randint(2000000000000000, 3000000000000000)
                work_center_id = random.randint(2000000000000000, 3000000000000000)
                operation_id = random.randint(2000000000000000, 3000000000000000)
                order_process_id = random.randint(2000000000000000, 3000000000000000)

                # 作业类型：0-人工，1-设备，2-委外，3-空闲，4-其他
                activity_class = random.randint(0, 4)
                activity_class_names = ["人工", "设备", "委外", "空闲", "其他"]

                # 数量和计量
                activity_qty = order["planned_quantity"]
                std_usage_qty = round(random.uniform(50, 200), 2)
                plan_usage_qty = round(std_usage_qty * 1.05, 2)
                usage_qty = round(random.uniform(0.5, 2.0), 4)
                denominator_qty = 1

                activity = {
                    "id": activity_id,
                    "lineNum": line_num,
                    "orderId": order_id,
                    "orderProductId": order_product_id,
                    "activityId": activity_id,
                    "activityType": activity_type_id,
                    "activityTypeCode": f"ACT{random.randint(100, 999)}",
                    "activityTypeName": f"{activity_class_names[activity_class]}作业",
                    "orderProcessId": order_process_id,
                    "opSn": base_proc["sequence"],
                    "activityClass": activity_class,

                    # 工作中心
                    "workCenterId": work_center_id,
                    "workCenterCode": base_proc["work_center_id"],
                    "workCenterName": base_proc["work_center_name"],

                    # 工序
                    "operationId": operation_id,
                    "operationCode": base_proc["process_code"],
                    "operationName": base_proc["process_name"],

                    # 单位
                    "activityUnit": random.randint(1000000000000000, 2000000000000000),
                    "activityUnitName": random.choice(["小时", "台时", "人时", "件"]),
                    "activityUnitPrecision": 5,
                    "activityUnitTruncationType": 4,
                    "usageUnit": random.randint(1000000000000000, 2000000000000000),
                    "usageUnitName": random.choice(["小时", "台时"]),
                    "usageUnitPrecision": 5,
                    "usageUnitTruncationType": 4,

                    # 数量
                    "stdUsageQty": std_usage_qty,
                    "planUsageQty": plan_usage_qty,
                    "denominatorQuantity": denominator_qty,
                    "usageQty": usage_qty,
                    "isCalcCost": random.choice([True, False]),
                    "activityQty": activity_qty,

                    # 计量基础：0-物料，1-批次
                    "usageBasis": random.choice([0, 1]),

                    # 自动创建：0-否，1-是
                    "isAutoCreate": random.choice([0, 1]),

                    # 时间戳
                    "pubts": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                }

                activities.append(activity)
                line_num += 10

        return activities

    @staticmethod
    def _generate_order_by_products(order: dict, product_info: dict, order_product_id: int) -> list:
        """生成订单联副产品明细（orderByProduct）- 用友云标准格式"""
        # 随机生成0-2个联副产品
        num_by_products = random.randint(0, 2)

        if num_by_products == 0:
            return []

        by_products = []

        for idx in range(num_by_products):
            by_product_id = random.randint(2000000000000000, 3000000000000000)
            material_id = random.randint(2000000000000000, 3000000000000000)
            product_id = random.randint(2000000000000000, 3000000000000000)
            sku_id = random.randint(2000000000000000, 3000000000000000)
            warehouse_id = random.randint(2000000000000000, 3000000000000000)

            # 产出类型：1-联产品，2-副产品
            production_type = random.choice(["1", "2"])
            production_type_name = "联产品" if production_type == "1" else "副产品"

            # 产出数量（副产品通常较少）
            if production_type == "2":
                quantity = round(order["planned_quantity"] * random.uniform(0.02, 0.1), 2)
            else:
                quantity = round(order["planned_quantity"] * random.uniform(0.3, 0.6), 2)

            # 单位产出数量（每个主产品产出多少副产品）
            unit_use_qty = round(quantity / order["planned_quantity"], 8) if order["planned_quantity"] > 0 else 0

            by_product = {
                "id": by_product_id,
                "orderProductLineNo": (idx + 1) * 10,
                "lineNo": (idx + 1) * 10,
                "orderProductId": order_product_id,

                # 物料信息
                "materialId": material_id,
                "materialCode": f"BP{random.randint(1000, 9999)}",
                "materialName": f"{production_type_name}{idx+1}",
                "manufacturingSpecification": f"规格-{idx+1}",
                "productId": product_id,
                "productCode": f"BP{random.randint(1000, 9999)}",
                "productName": f"{production_type_name}{idx+1}",
                "skuId": sku_id,
                "skuCode": f"BP{random.randint(1000, 9999)}",
                "skuName": f"{production_type_name}{idx+1}",

                # 产出类型
                "productionType": production_type,

                # 组织
                "orgId": str(random.randint(1000000000000000, 2000000000000000)),
                "orgName": order["organization"],

                # 数量
                "quantity": quantity,
                "unitUseQuantity": unit_use_qty,
                "numeratorQuantity": unit_use_qty,
                "denominatorQuantity": 1,

                # 单位和精度
                "productionUnitId": random.randint(1000000000000000, 2000000000000000),
                "productUnitName": product_info["unit"],
                "productUnitPrecision": 8,
                "productUnitTruncationType": 4,
                "mainUnit": random.randint(1000000000000000, 2000000000000000),
                "mainUnitName": product_info["unit"],
                "mainUnitPrecision": 8,
                "mainUnitTruncationType": 4,

                # 换算
                "changeRate": 1.0,
                "changeType": 0,

                # 仓库
                "warehouseId": warehouse_id,
                "warehouseName": random.choice(["成品仓", "半成品仓", "副产品仓"]),

                # 产出日期
                "productionDate": order["plan_end_date"],

                # 批次和效期管理
                "isBatchManage": random.choice([True, False]),
                "isExpiryDateManage": random.choice([True, False]),

                # 表外产出
                "offChartReceipt": random.choice([True, False]),

                # 确认入库数量
                "cfmIncomingQty": 0,
                "cfmIncomingAuxQty": 0,
                "cfmScrapStockQty": 0,
                "cfmScrapStockAuxQty": 0,

                # 时间戳
                "pubts": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }

            by_products.append(by_product)

        return by_products

    @staticmethod
    def _generate_sum_record(record_list: list) -> list:
        """生成合计记录（sumRecordList）"""
        if not record_list:
            return []

        # 计算合计（容错：字段缺失时按0处理）
        def num(x):
            try:
                return float(x)
            except Exception:
                return 0.0

        total_quantity = sum(num(r.get("OrderProduct_quantity", 0)) for r in record_list)
        total_auxiliary_quantity = sum(num(r.get("OrderProduct_auxiliaryQuantity", 0)) for r in record_list)
        total_mrp_quantity = sum(num(r.get("OrderProduct_mrpQuantity", 0)) for r in record_list)

        return [{
            "OrderProduct_quantity": total_quantity,
            "OrderProduct_auxiliaryQuantity": total_auxiliary_quantity,
            "OrderProduct_mrpQuantity": total_mrp_quantity,
            "mainUnitPrecision": 3,
            "productUnitPrecision": 3
        }]

    @staticmethod
    def get_order_detail(order_id: str, code: Optional[str] = None, numeric_id: Optional[int] = None) -> dict:
        """获取生产订单详情
        优先从 data/erp_order_details_*.json 装载；不存在时回退到脚本生成。

        入参兼容：
        - order_id: 历史兼容（形如 ORD0001），回退生成器使用
        - code: 订单编码（形如 SCDD2025...），用于文件查找
        - numeric_id: 明细中的长整型 id，用于文件查找
        """
        # 文件优先：按 numeric_id > code 匹配
        details = ProductionService._load_details_from_file()
        if details:
            hit = None
            if numeric_id is not None:
                for item in details:
                    try:
                        if int(item.get("id")) == int(numeric_id):
                            hit = item
                            break
                    except Exception:
                        continue
            if not hit and code:
                for item in details:
                    if str(item.get("code", "")) == str(code):
                        hit = item
                        break
            if hit:
                return hit

        # 回退：仍使用生成器（兼容旧调用方）
        # 验证订单ID格式
        try:
            if not order_id or not isinstance(order_id, str):
                raise ValueError("订单ID不能为空")
            if not order_id.startswith('ORD'):
                raise ValueError(f"无效的订单ID格式: {order_id}")
            order_num = int(order_id.replace('ORD', ''))
        except (ValueError, AttributeError):
            raise ValueError(f"无效的订单ID格式: {order_id}")

        order = DataGenerator.generate_realistic_order(order_num)
        product_info = order["product_info"]

        materials = DataGenerator.generate_order_materials(product_info, order["planned_quantity"])
        processes = DataGenerator.generate_order_processes(product_info["product_type"])

        return {
            "order_info": {
                "id": order["id"],
                "code": order["code"],
                "status": order["status"],
                "status_name": order["status_name"],
                "organization": order["organization"],
                "department": order["department"],
                "priority": order["priority"],
                "customer": order["customer"],
                "contract_no": order["contract_no"],
                "created_by": order["created_by"],
                "created_time": order["created_time"],
            },
            "product_info": product_info,
            "quantity_info": {
                "planned_quantity": order["planned_quantity"],
                "completed_quantity": order["completed_quantity"],
                "qualified_quantity": order["qualified_quantity"],
                "scrap_quantity": order["scrap_quantity"],
                "return_quantity": random.randint(0, int(order["completed_quantity"] * 0.02)),
                "remaining_quantity": order["planned_quantity"] - order["completed_quantity"],
            },
            "date_info": {
                "plan_start_date": order["plan_start_date"],
                "plan_end_date": order["plan_end_date"],
                "actual_start_date": (datetime.now() - timedelta(days=random.randint(0, 3))).isoformat() if order["status"] in ["5", "9"] else None,
                "actual_end_date": (datetime.now() - timedelta(days=random.randint(0, 2))).isoformat() if order["status"] == "9" else None,
            },
            "materials": materials,
            "processes": processes,
            "quality_info": {
                "inspection_status": random.choice(["pending", "passed", "failed"]) if order["completed_quantity"] > 0 else "pending",
                "inspector": random.choice(["质检员张师傅", "质检员李师傅", "质检员王师傅"]),
                "inspection_date": (datetime.now() - timedelta(days=random.randint(0, 2))).isoformat() if order["completed_quantity"] > 0 else None,
                "quality_level": random.choice(["A级", "B级", "C级"]) if order["qualified_quantity"] > 0 else None,
            },
        }

    @staticmethod
    def save_completion_report(data: dict) -> dict:
        """保存完工报告（用友标准格式）"""
        # 提取表头字段
        org_code = data.get('orgCode')
        trans_type_id = data.get('transTypeId')
        vouch_date = data.get('vouchdate')
        dept_code = data.get('productionDepartmentCode', '')
        operator_id = data.get('operatorId', '')
        off_chart = data.get('offChartReceipt', False)
        remark = data.get('remark', '')
        report_code = data.get('code', '')

        # 获取明细数据
        details = data.get('finishedReportDetail', [])
        if not details:
            raise ValueError("完工报告明细不能为空")

        # 处理明细数据并验证
        processed_details = []
        total_success = 0

        for idx, detail in enumerate(details):
            # 提取明细字段
            production_type = detail.get('productionType', '0')
            product_code = detail.get('productCode', '')
            material_code = detail.get('materialCode', product_code)
            sku_code = detail.get('skuCode', product_code)
            batch_no = detail.get('batchNo', '')
            production_unit_code = detail.get('productionUnitCode', 'kg')
            quantity = detail.get('quantity', 0)
            qualified_qty = detail.get('qualifiedQuantity', quantity)
            scrap_qty = detail.get('scrapQuantity', 0)
            return_qty = detail.get('returnQuantity', 0)
            auxiliary_qty = detail.get('auxiliaryQuantity', quantity)
            inspection = detail.get('inspection', False)
            stock_by_inspection = detail.get('stockByInspection', False)
            detail_org_code = detail.get('orgCode', org_code)
            warehouse_id = detail.get('warehouseId', '')
            warehouse_code = detail.get('warehouseCode', warehouse_id)
            finish_date = detail.get('finishDate', datetime.now().isoformat())
            change_rate = detail.get('changeRate', 1.0)
            scrap_reason = detail.get('scrapReason', '')
            return_reason = detail.get('returnReason', '')

            # 数量平衡验证（严格）
            if abs(quantity - (qualified_qty + scrap_qty + return_qty)) > 0.0001:
                raise ValueError(
                    f"创建失败！合格数量报废数量返工数量之和必须等于完工数量。"
                    f"明细[{idx}]: 完工数量={quantity}, 合格={qualified_qty}, 报废={scrap_qty}, 返工={return_qty}"
                )

            # 构建明细数据
            detail_id = random.randint(2000000000000000, 3000000000000000)
            processed_details.append({
                "id": str(detail_id),
                "lineNo": (idx + 1) * 10,
                "productionType": production_type,
                "materialId": random.randint(1000000000000000, 2000000000000000),
                "materialCode": material_code,
                "productId": random.randint(1000000000000000, 2000000000000000),
                "productCode": product_code,
                "skuId": random.randint(1000000000000000, 2000000000000000),
                "skuCode": sku_code,
                "batchNo": batch_no,
                "productionUnitId": random.randint(1000000000000000, 2000000000000000),
                "productionUnitCode": production_unit_code,
                "quantity": quantity,
                "auxiliaryQuantity": auxiliary_qty,
                "qualifiedQuantity": qualified_qty,
                "qualifiedAuxiliaryQuantity": int(qualified_qty * change_rate),
                "scrapQuantity": scrap_qty,
                "scrapAuxiliaryQuantity": int(scrap_qty * change_rate),
                "returnQuantity": return_qty,
                "returnAuxiliaryQuantity": int(return_qty * change_rate),
                "changeType": "0" if change_rate == 1.0 else "1",
                "changeRate": change_rate,
                "inspection": inspection,
                "stockByInspection": stock_by_inspection,
                "orgId": detail_org_code,
                "warehouseId": warehouse_code,
                "finishDate": finish_date,
                "scrapReason": scrap_reason,
                "returnReason": return_reason,
                "isSerialNoManage": False,
                "pubts": datetime.now().isoformat()
            })
            total_success += 1

        # 模拟成功率
        is_success = random.random() > (1 - config.MOCK_SUCCESS_RATE)

        if is_success:
            # 生成主表ID和编码
            report_id = random.randint(2000000000000000, 3000000000000000)
            if not report_code:
                report_code = f"WGBG{datetime.now().strftime('%Y%m%d')}{str(random.randint(1000, 9999))}"

            # 返回用友标准响应格式
            return {
                "count": 1,
                "sucessCount": 1,
                "failCount": 0,
                "messages": {},
                "infos": {
                    "id": str(report_id),
                    "orgId": org_code,
                    "transTypeId": trans_type_id,
                    "productionDepartmentId": dept_code,
                    "code": report_code,
                    "vouchdate": vouch_date,
                    "status": 0,  # 0:开立, 1:已审核, 9:已完工
                    "creator": operator_id if operator_id else "系统用户",
                    "creatorId": operator_id if operator_id else str(random.randint(1000000000000000, 2000000000000000)),
                    "createDate": datetime.now().isoformat(),
                    "isWfControlled": False,
                    "pubts": datetime.now().isoformat(),
                    "tenant": random.randint(1000000000000000, 2000000000000000),
                    "isSnManage": False,
                    "offChartReceipt": off_chart,
                    "firstCheck": "0",
                    "remark": remark,
                    "finishedReportDetail": processed_details
                }
            }
        else:
            raise Exception(random.choice([
                "数量平衡验证失败",
                "工序状态不符合要求",
                "质量数据异常",
                "成本核算系统错误",
                "原材料库存不足",
                "设备状态异常"
            ]))

    @staticmethod
    def save_batch_completion_reports(batch_data: dict) -> dict:
        """批量保存完工报告"""
        reports = batch_data.get('reports', [])
        if not reports:
            raise ValueError("报告列表不能为空")

        success_count = 0
        failed_reports = []

        for i, report_data in enumerate(reports):
            try:
                # 单个报告处理
                ProductionService.save_completion_report(report_data)
                success_count += 1
            except Exception as e:
                failed_reports.append({
                    "index": i,
                    "order_id": report_data.get('order_id'),
                    "error": str(e)
                })

        # 模拟批量处理成功率
        batch_success = random.random() > (1 - config.MOCK_SUCCESS_RATE)

        if batch_success or success_count > 0:
            return {
                "batch_id": f"BATCH{datetime.now().strftime('%Y%m%d')}{str(random.randint(1000, 9999))}",
                "total_reports": len(reports),
                "success_count": success_count,
                "failed_count": len(failed_reports),
                "failed_reports": failed_reports,
                "success_rate": round(success_count / len(reports) * 100, 2),
                "process_time": datetime.now().isoformat()
            }
        else:
            raise Exception("批量完工报告处理失败")

    @staticmethod
    def collect_realtime_production_data(data: dict) -> dict:
        """采集实时生产数据"""
        device_id = data.get('device_id')
        order_id = data.get('order_id')
        process_id = data.get('process_id')

        if not all([device_id, order_id]):
            raise ValueError("设备ID和订单ID不能为空")

        # 模拟实时数据
        realtime_data = {
            "device_id": device_id,
            "order_id": order_id,
            "process_id": process_id,
            "timestamp": datetime.now().isoformat(),
            "production_data": {
                "current_speed": round(random.uniform(50, 200), 2),  # 当前速度 (m/min)
                "total_length": round(random.uniform(1000, 5000), 2),  # 总长度 (m)
                "current_tension": round(random.uniform(100, 500), 2),  # 当前张力 (N)
                "temperature": round(random.uniform(180, 220), 2),  # 温度 (°C)
                "pressure": round(random.uniform(0.5, 2.5), 2),  # 压力 (MPa)
                "power_consumption": round(random.uniform(15, 45), 2),  # 功耗 (kW)
                "operating_hours": round(random.uniform(1, 8), 2),  # 运行时间 (h)
                "output_per_hour": round(random.uniform(80, 150), 2)  # 小时产量 (m/h)
            },
            "quality_data": {
                "diameter": round(random.uniform(8.0, 12.0), 3),  # 外径 (mm)
                "thickness": round(random.uniform(1.2, 2.0), 3),  # 壁厚 (mm)
                "eccentricity": round(random.uniform(0.05, 0.15), 3),  # 偏心率
                "surface_quality": random.choice(["excellent", "good", "fair", "poor"]),
                "defect_count": random.randint(0, 3),
                "defect_types": random.sample(["scratches", "bumps", "color_diff"], random.randint(0, 2))
            },
            "device_status": {
                "status": random.choice(["running", "stopped", "alarm", "maintenance"]),
                "alarm_codes": [f"ALM{random.randint(100, 999)}"] if random.random() < 0.1 else [],
                "maintenance_flag": random.random() < 0.05,
                "efficiency": round(random.uniform(75, 95), 2)
            }
        }

        # 模拟数据采集成功率
        is_success = random.random() > (1 - config.MOCK_SUCCESS_RATE)

        if is_success:
            return {
                "data_id": f"RT{datetime.now().strftime('%Y%m%d%H%M%S')}{str(random.randint(100, 999))}",
                "collection_time": datetime.now().isoformat(),
                "realtime_data": realtime_data,
                "data_quality": "good" if realtime_data["device_status"]["status"] == "running" else "warning",
                "next_collection_time": (datetime.now() + timedelta(minutes=5)).isoformat()
            }
        else:
            raise Exception("数据采集失败: 设备通讯异常或数据校验失败")

    @staticmethod
    def save_process_completion_report(data: dict) -> dict:
        """保存工序级完工报告"""
        required_fields = ['order_id', 'process_id', 'process_name', 'completed_quantity']
        for field in required_fields:
            if not data.get(field):
                raise ValueError(f"{field}不能为空")

        # 验证订单ID格式
        order_id = data['order_id']
        try:
            if not order_id or not isinstance(order_id, str):
                raise ValueError("订单ID不能为空")
            if not order_id.startswith('ORD'):
                raise ValueError(f"无效的订单ID格式: {order_id}")
            order_num = int(order_id.replace('ORD', ''))
        except (ValueError, AttributeError) as e:
            raise ValueError(f"无效的订单ID格式: {order_id}")

        # 获取订单信息
        order = DataGenerator.generate_realistic_order(order_num)

        process_id = data['process_id']
        completed_qty = data['completed_quantity']
        qualified_qty = data.get('qualified_quantity', completed_qty)

        # 模拟成功率
        is_success = random.random() > (1 - config.MOCK_SUCCESS_RATE)

        if is_success:
            report_id = f"PROC{datetime.now().strftime('%Y%m%d')}{str(random.randint(1000, 9999))}"

            return {
                "report_id": report_id,
                "report_code": f"PCR-{report_id}",
                "status": "submitted",
                "status_name": "已提交",
                "submit_time": datetime.now().isoformat(),
                "order_id": data['order_id'],
                "order_code": order["code"],
                "process_id": process_id,
                "process_name": data['process_name'],
                "work_center_id": data.get('work_center_id', f"WC{random.randint(1, 60):03d}"),
                "work_center_name": data.get('work_center_name', f"工作中心{random.randint(1, 20)}"),
                "completed_quantity": completed_qty,
                "qualified_quantity": qualified_qty,
                "scrap_quantity": data.get('scrap_quantity', 0),
                "return_quantity": data.get('return_quantity', 0),
                "efficiency": round(qualified_qty / completed_qty * 100, 2) if completed_qty > 0 else 0,
                "quality_grade": "A级" if qualified_qty / completed_qty >= 0.98 else "B级" if qualified_qty / completed_qty >= 0.95 else "C级",
                "actual_start_time": data.get('actual_start_time', (datetime.now() - timedelta(hours=2)).isoformat()),
                "actual_end_time": data.get('actual_end_time', datetime.now().isoformat()),
                "standard_hours": data.get('standard_hours', round(random.uniform(1.0, 4.0), 2)),
                "actual_hours": data.get('actual_hours', round(random.uniform(0.8, 5.0), 2)),
                "operator": data.get('operator', random.choice(["操作员A", "操作员B", "操作员C", "操作员D"])),
                "inspector": data.get('inspector', random.choice(["质检员张师傅", "质检员李师傅", "质检员王师傅"])),
                "equipment_id": data.get('equipment_id', f"EQ{random.randint(1, 20):03d}"),
                "next_process": data.get('next_process', "下一道工序"),
                "remarks": data.get('remarks', random.choice(["正常生产", "设备调试", "工艺改进", "质量提升"]))
            }
        else:
            raise Exception(random.choice([
                "工序状态不符合要求",
                "质量数据异常",
                "设备状态异常",
                "工艺参数超出范围"
            ]))

    @staticmethod
    def get_completion_reports_list(page: int, page_size: int, filters: dict = None) -> dict:
        """获取完工报告列表"""
        # 生成模拟完工报告数据
        reports = []
        total_reports = 89  # 模拟总数

        # 模拟一些过滤器
        filters = filters or {}

        # 计算实际需要生成的记录数
        start_idx = (page - 1) * page_size
        end_idx = min(start_idx + page_size, total_reports)
        records_to_generate = max(0, end_idx - start_idx)

        # 生成当前页的完工报告（倒序排列，最新的在前面）
        for i in range(records_to_generate):
            # 倒序计算report_num，使最新报告排在最前面
            report_num = total_reports - start_idx - i

            # 生成报告数据
            products = [
                'YJV 3×50+1×25 0.6/1kV 电力电缆',
                'KVV 4×1.5 450/750V 控制电缆',
                'JKLYJ 70 10kV 架空线',
                'VV 4×35 0.6/1kV 电力电缆',
                'NH-YJV 3×95+1×50 0.6/1kV 耐火电力电缆'
            ]

            quality_grades = ['A级', 'B级', 'C级']
            shifts = ['白班', '夜班']
            workshops = ['电力电缆车间', '控制电缆车间', '架空线车间']

            completed_qty = random.randint(200, 2000)
            qualified_qty = int(completed_qty * random.uniform(0.92, 0.99))
            efficiency = round((qualified_qty / completed_qty) * 100, 2)
            quality_grade = 'A级' if efficiency >= 98 else ('B级' if efficiency >= 95 else 'C级')

            # 倒序时间：report_num越大（越新的记录），时间越近
            days_ago = total_reports - report_num
            submit_time = (datetime.now() - timedelta(days=days_ago, hours=random.randint(0, 23), minutes=random.randint(0, 59))).isoformat()

            reports.append({
                "report_id": f"RPT{datetime.now().strftime('%Y%m%d')}{str(report_num).zfill(4)}",
                "report_code": f"CR-{datetime.now().strftime('%Y%m')}-{str(report_num).zfill(4)}",
                "order_id": f"ORD{str(report_num).zfill(8)}",
                "order_code": f"MO-{datetime.now().strftime('%Y%m')}-{str(report_num).zfill(4)}",
                "product_code": f"PROD{str(report_num).zfill(3)}",
                "product_name": products[report_num % len(products)],
                "completed_quantity": completed_qty,
                "qualified_quantity": qualified_qty,
                "scrap_quantity": completed_qty - qualified_qty,
                "return_quantity": random.randint(0, int(completed_qty * 0.02)),
                "efficiency": efficiency,
                "quality_grade": quality_grade,
                "workshop": random.choice(workshops),
                "shift": random.choice(shifts),
                "operator": random.choice(["操作员A", "操作员B", "操作员C"]),
                "inspector": random.choice(["质检员张师傅", "质检员李师傅", "质检员王师傅"]),
                "submit_time": submit_time,
                "status": "submitted",
                "status_name": "已提交",
                "estimated_cost": round(completed_qty * random.uniform(18.0, 32.0), 2),
                "material_cost": round(completed_qty * random.uniform(12.0, 25.0), 2),
                "labor_cost": round(completed_qty * random.uniform(3.0, 8.0), 2),
                "overhead_cost": round(completed_qty * random.uniform(2.0, 6.0), 2),
                "remarks": random.choice(["正常生产", "设备调试", "工艺改进", "质量提升"])
            })

        # 计算汇总统计
        total_completed = sum(r["completed_quantity"] for r in reports)
        total_qualified = sum(r["qualified_quantity"] for r in reports)
        avg_efficiency = round((total_qualified / total_completed * 100), 2) if total_completed > 0 else 0

        return {
            "total": total_reports,
            "page": page,
            "page_size": page_size,
            "pages": (total_reports + page_size - 1) // page_size,
            "reports": reports,
            "summary": {
                "total_reports": total_reports,
                "total_completed_quantity": total_completed,
                "total_qualified_quantity": total_qualified,
                "average_efficiency": avg_efficiency,
                "today_reports": random.randint(5, 20),
                "this_month_reports": random.randint(50, 150)
            }
        }

    @staticmethod
    def update_order_status(order_id: str, new_status: str, update_data: dict = None) -> dict:
        """更新订单状态"""
        status_names = {
            "0": "开立",
            "1": "已审核",
            "2": "已关闭",
            "5": "已开工",
            "9": "已完工"
        }

        if new_status not in status_names:
            raise ValueError(f"无效的订单状态: {new_status}")

        # 模拟成功率
        is_success = random.random() > (1 - config.MOCK_SUCCESS_RATE)

        if is_success:
            return {
                "order_id": order_id,
                "old_status": random.choice(["0", "1", "5"]),
                "new_status": new_status,
                "status_name": status_names[new_status],
                "update_time": datetime.now().isoformat(),
                "updated_by": update_data.get('updated_by', "系统用户") if update_data else "系统用户",
                "update_reason": update_data.get('reason', "状态变更") if update_data else "状态变更",
                "success": True
            }
        else:
            raise Exception(random.choice([
                "订单状态转换不允许",
                "订单数据验证失败",
                "权限不足",
                "订单已被锁定"
            ]))
